<template>
  <div class="tinymce-container">
    <div v-if="inline" :id="editId"/>
    <textarea v-else :id="editId"/>
  </div>
</template>
<script>
import 'tinymce/tinymce.min.js'
import 'tinymce/themes/silver/theme.min.js'
import 'tinymce/plugins/print/plugin.min.js'
import 'tinymce/plugins/preview/plugin.min.js'
import 'tinymce/plugins/paste/plugin.min.js'
import 'tinymce/plugins/importcss/plugin.min.js'
import 'tinymce/plugins/searchreplace/plugin.min.js'
import 'tinymce/plugins/autolink/plugin.min.js'
import 'tinymce/plugins/autosave/plugin.min.js'
import 'tinymce/plugins/save/plugin.min.js'
import 'tinymce/plugins/directionality/plugin.min.js'
import 'tinymce/plugins/code/plugin.min.js'
import 'tinymce/plugins/visualblocks/plugin.min.js'
import 'tinymce/plugins/visualchars/plugin.min.js'
import 'tinymce/plugins/fullscreen/plugin.min.js'
import 'tinymce/plugins/image/plugin.min.js'
import 'tinymce/plugins/link/plugin.min.js'
import 'tinymce/plugins/media/plugin.min.js'
import 'tinymce/plugins/template/plugin.min.js'
import 'tinymce/plugins/codesample/plugin.min.js'
import 'tinymce/plugins/table/plugin.min.js'
import 'tinymce/plugins/charmap/plugin.min.js'
import 'tinymce/plugins/hr/plugin.min.js'
import 'tinymce/plugins/pagebreak/plugin.min.js'
import 'tinymce/plugins/nonbreaking/plugin.min.js'
import 'tinymce/plugins/anchor/plugin.min.js'
import 'tinymce/plugins/toc/plugin.min.js'
import 'tinymce/plugins/insertdatetime/plugin.min.js'
import 'tinymce/plugins/advlist/plugin.min.js'
import 'tinymce/plugins/lists/plugin.min.js'
import 'tinymce/plugins/wordcount/plugin.min.js'
import 'tinymce/plugins/imagetools/plugin.min.js'
import 'tinymce/plugins/textpattern/plugin.min.js'
import 'tinymce/plugins/noneditable/plugin.min.js'
import 'tinymce/plugins/help/plugin.min.js'
import 'tinymce/plugins/quickbars/plugin.min.js'
import 'tinymce/plugins/emoticons/plugin.min.js'
import 'tinymce/plugins/emoticons/js/emojis.min.js'

import *  as storageStreamApi from '@/apis/oss/stream'

let basePrefix = '/static/tinymce'

  export default {
    name: 'tinymce-editor',
    props: {
      editId: {type: String, default: () => 'tinymce_' + String(Date.now()) + (Math.random() * 1000).toFixed(0)},
      config: {type:Object},
      state: {type:Object},
      height: {type:Number,default:500},
      inline: {type: Boolean, default: false},
      content: {type: String, default: ''},
      disabled: {type: Boolean, default: false},
    },
    data() {
      return {
        hasInit: false,
        hasChange:false,
        fullscreen:false,
        editor: null,
        default: {}
      }
    },
    destroyed() {
      this.destroy()
    },
    created() {

    },
    watch: {
      disabled() {
        this.editor.setMode(this.disabled ? 'readonly' : 'design');
      }
    },
    mounted() {
      /**
       * webpack在打包Promise异步模块时，如果全局只出现过一次，依然会打包到组件中
       */
      /*new Promise(() => {
        if (!window.tinymce) {
          require('tinymce/tinymce')
          require('tinymce/themes/silver')
        }
      }).then(
        this.initEditor()
      )*/
      this.initEditor()
    },
    methods: {
      initEditor() {
        //指定异步请求加载的默认路径
        window.tinymce.baseURL = window.tinymce.baseURI.protocol + "://" + window.tinymce.baseURI.authority + basePrefix
        //指定异步请求加载的文件标识
        window.tinymce.suffix = '.min'
        if(this.hasInit){return}
        /*
         * 全功能实现参考官方：https://www.tiny.cloud/docs/demo/full-featured/
         * 当不通过import映入插件时，tinymce会在网页中异步请求加载plugins中指定的插件对象，同时需要将对应插件node_modules/tinymce/plugins文件拷贝到public/static/tinymce/plugins
         * 皮肤样式文件需要将node_modules/tinymce/skins文件拷贝到public/static/tinymce/skins ，皮肤文件默认通过异步请求
         * 语言文件需要从官方下载后拷贝到public/static/tinymce/langs下 ，语言文件默认通过异步请求
         */
        window.tinymce.init(Object.assign({},{
          selector: `#${this.editId}`,
          readonly: this.disabled,
          //theme: 'silver',
          //language_url: basePrefix+`/langs/zh_CN.js`,
          language: 'zh_CN',
          //skin_url: basePrefix+`/skins/ui/oxide`,
          //content_css: basePrefix+`/skins/content/default/content.css`,
          height: this.height,
          body_class: 'panel-body ',
          object_resizing: false,
          plugins: 'print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern noneditable help charmap quickbars emoticons',
          //menubar: 'file edit view insert format tools table help',
          menubar: false, // 隐藏最上方menu
          toolbar: 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent ltr rtl |  numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | insertfile  image media |template link anchor codesample | fullscreen  preview save print |',
          toolbar_sticky: true,
          toolbar_drawer: 'sliding',
          contextmenu: "link image imagetools table",
          browser_spellcheck: true, // 拼写检查
          branding: false, // 去水印,开源协议要求必须显示
          elementpath: false,  //禁用编辑器底部的状态栏
          statusbar: false, // 隐藏编辑器底部的状态栏
          paste_data_images: true, // 允许粘贴图像
          image_title: false, // 是否开启图片标题设置的选择，这里设置否
          image_caption: true,
          image_advtab: true,
          autosave_ask_before_unload: true,
          autosave_interval: "30s",
          autosave_prefix: "{path}{query}-{id}-",
          autosave_restore_when_empty: false,
          autosave_retention: "2m",
          convert_urls: false,
          paste_auto_cleanup_on_paste : true,
          paste_remove_styles: true,
          paste_remove_styles_if_webkit: true,
          paste_strip_class_attributes: true,

          //自定义文件选择器的位置
          //file_browser_callback_types: 'file image media',
          file_picker_types: 'file image media',
          //自定义文件选择器的回调内容
          file_picker_callback: function (callback, value, meta) {
            let input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.onchange=function () {
              let formData = new FormData();
              if(this.files) {
                let file = this.files[0]
                formData.append('srcFile', file);
                formData.append('bucket', 'tinymce')
                formData.append('meta', meta)
                storageStreamApi.upload(formData).then(response => {
                  let {status, result} = response
                  if (status == 200) {
                    let accessUrl = (process.env.VUE_APP_BASE_API || process.env.baseURL || process.env.apiUrl || "") +"/"+ result.accessUrl
                    callback(accessUrl, {title: file.name});
                  }
                })
              }
            }
            input.click();
          },
          init_instance_callback: editor => {
            if (this.content) {
              editor.setContent(this.content)
            }
            this.hasInit = true
            editor.on('NodeChange Change KeyUp SetContent', () => {
              this.hasChange = true
              this.$emit('input', editor.getContent())
            })
          },
          setup(editor) {
            editor.on('FullscreenStateChanged', (e) => {
              this.fullscreen = e.state
            })
            /*editor.ui.registry.addButton('insertfile', {
              text: 'upload',
              icon:'insert-file',
              onAction: function (_) {
                let input = document.createElement('input');
                input.setAttribute('type', 'file');
                input.onchange=function () {
                  let formData = new FormData();
                  if(this.files) {
                    let file = this.files[0]
                    formData.append('srcFile', file);
                    formData.append('bucket', 'tinymce')
                    storageStreamApi.upload(formData).then(response => {
                      let {status, message, result} = response
                      if (status == 200) {
                        let accessUrl = (process.env.VUE_APP_BASE_API || process.env.baseURL || process.env.apiUrl || "") + result.accessUrl
                        console.log(accessUrl)
                        editor.insertContent('&nbsp;<strong>'+accessUrl+'</strong>&nbsp;');
                      }
                    })
                  }
                }
                input.click();
                //editor.insertContent('&nbsp;<strong>It\'s my button!</strong>&nbsp;');
              }
            });*/
          },
          //图片上传处理
          images_upload_handler: (blobInfo, success,failure) => {
            //直接用了base64的图片形式上传图片
            // const img = 'data:image/jpeg;base64,' + blobInfo.base64()
            // success(img)

            let formData = new FormData();
            formData.append('srcFile', blobInfo.blob(),blobInfo.filename());
            formData.append('bucket','tinymce')
            storageStreamApi.upload(formData).then(response=>{
              let{status,message,result}=response
              debugger
              if(status==200){
                success((process.env.VUE_APP_BASE_API || process.env.baseURL || process.env.apiUrl || "")+"/"+result.accessUrl);
              }else{
                failure('文件上传失败:(' + status+'):'+message);
              }
            })
          },
        }))

        this.editor = window.tinymce.get(this.editId)
      },
      clear() {
        this.editor.setContent('')
      },
      destroy() {
        this.editor.destroy()
      },
      setContent(value) {
        this.editor.setContent(value)
      },
      getContent() {
        this.editor.getContent()
      },
    }
  }

</script>
<style lang="scss" scoped>

</style>
